package com.example.jcextend.utils;

import com.example.jcextend.context.SpringContextUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;

import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 文档导出工具
 */
public class ExportWordUtil {

    private static final String SUFFIX=".doc";


    //集成Freemarker
    private static Configuration configuration=null;


    //初始化
    static {
        configuration=new Configuration();
        configuration.setDefaultEncoding("UTF-8");                                                          //指定编码
        configuration.setClassForTemplateLoading(ExportWordUtil.class,"/template");    //指定模版的位置
        //configuration.setDirectoryForTemplateLoading(new File("F://文件的目录//"));
        //模板会从 ExportWordUtil 类所在的包的 /template/word 目录中查找
    }

    /**
     * 导出文件
     * @param map       模版要的数据
     * @param title    导出文件的名字
     * @param fltName  模版的位置
     */
    public static void exportWord(Map map,String title,String fltName) throws Exception {
        //获得模版
        Template template = configuration.getTemplate(fltName);

        //导入导出我们使用流来实现文档的导入导出,读进来写出去
        File file=null;
        InputStream inputStream=null;

        //因为我们是写到客户端所以我们使用这个输出流
        ServletOutputStream out=null;

        //初始化doc文件
        file=creatDocFile(map,template);

        inputStream=new FileInputStream(file);

        //导出的文件名字
        String fileName=title+SUFFIX;

        //通过Response写出去
        HttpServletResponse servletResponse = SpringContextUtils.getHttpServletResponse();
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("application/msword");       //指定文件的类型

        //初始化输出流
        out=servletResponse.getOutputStream();

        //这行代码的目的是将文件以附件的形式下载，并且在下载时使用fileName作为显示在用户下载的文件名,文件名我们也指定编码,否则乱码了
        servletResponse.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));

        //写文件
        //定义缓冲区
        byte[] buffer=new byte[512];
        int bytesToRead=-1;

        //没有读完
        while ((bytesToRead = inputStream.read(buffer))!= -1){
            out.write(buffer,0,bytesToRead);
            //值为0表示从buffer的起始位置开始写入。
        }

        //释放资源
        if (inputStream != null){
            inputStream.close();
        }

        if (out!=null){
            out.close();
        }

        if (file!=null){
            //删除文件
            file.delete();
        }
    }

    //创建doc文件给file赋值,传递数据和指定的模版
    private static File creatDocFile(Map dataMap,Template template) throws Exception {
        //需要渲染的过程但是要通过临时文件操作
        File file=new File("init.doc");

        Writer writer = new OutputStreamWriter(new FileOutputStream(file), "utf-8");

        //渲染数据
        template.process(dataMap,writer);

        writer.close();

        //返回文件
        return file;
    }



}
